#include"String.h"

String::String()
    :_size(0)
    ,_capacity(0)
    ,_str(new char[1]{ '\0' })   // 空字符有'\0', 这里为了跟析构兼容，不写成new char('\0')
    {}

String::String(const char* s)
    :_size(strlen(s))       // 注意：初始化列表是按声明的顺序依次初始化
    ,_capacity(_size)
    ,_str(new char[_capacity + 1]) // 这里要多开一个存'\0'
{
    strcpy(_str, s);    // 将s拷贝到_str
}


String::String(size_t n, char c)
    :_size(n)
    ,_capacity(_size)
    ,_str(new char[_capacity + 1])
{
    for(int i = 0; i < n; i++) _str[i] = c;
    _str[n] = '\0';
}

String::~String()
{
    delete[] _str;
    _size = _capacity = 0;
}

void String::reserve(size_t n)
{
    if(n > _capacity)
    {
        char* t = new char[n + 1];
        strcpy(t, _str);
        delete[] _str;
        _str = t;
        _capacity = n;
    }
}

void String::resize(size_t n)
{
    if(n < _size) _size = n;
    else{
        reserve(n);
        memset(&_str[_size], '\0', sizeof(char) * (n - _size));
        _size = n;
    }
    _str[_size] = '\0';
}

void String::push_back(char c)
{
    if(_size == _capacity)
        reserve(_capacity == 0 ? 10 : 2*_capacity);
    _str[_size++] = c;
    _str[_size] = '\0'; // 注意别漏了
}

String& String::operator+=(char c)
{
    push_back(c);
    return *this;
}

String& String::operator+=(const char* s)
{
    size_t n = strlen(s);
    reserve(_size + n);
    for(int i = 0; i < n; i++)
        push_back(s[i]);
    return *this;
}

String& String::operator+=(const String& str)
{
    *this += str.c_str();
    return *this;
}

String& String::insert(size_t pos, const char* s)
{
    assert(pos <= _size);
    int n = strlen(s);
    reserve(_size + n);
    memmove(&_str[pos + n], &_str[pos], sizeof(char) * (_size - pos));
    memcpy(&_str[pos], s, sizeof(char) * n);
    _size += n;
    _str[_size] = '\0';
    return *this;
}

// const size_t String::npos = -1; // 类外定义

String& String::erase(size_t pos, size_t len)
{
    assert(pos <= _size);

    // len 大于后面字符个数，有多少删多少
    if(len > _size - pos) _size = pos;
    else{
        memcpy(&_str[pos], &_str[pos + len], sizeof(char) * (_size - (pos + len)));
        _size -= len;
    }
    _str[_size] = '\0';
    return *this;
}

size_t String::find(char c, size_t pos) const
{
    for(int i = pos; i < _size; i++)
        if(_str[i] == c)
            return i;
    return npos;
}
size_t String::find(const char* s, size_t pos) const
{
    int n = strlen(s);
    for(int i = pos; i < _size; i++)
    {
        int j = 0, k = i;
        for(; j < n; j++, k++)
            if(_str[k] != s[j])
                break;
        if(j == n) return i;
    }
    return npos;
}
size_t String::find(const String& str, size_t pos) const
{
    return find(str.c_str(), pos);
}

String::String(const String& str)
    :_size(str._size)
    ,_capacity(_size)
    ,_str(new char[_capacity + 1])
{
    strcpy(_str, str.c_str());
}

String& String::operator= (const String& str)
{
    // char* tmp = new char[str._size + 1];
    // strcpy(tmp, str._str);
    // delete[] _str;
    // _str = tmp;
    // _size = _capacity = str._size;
    if(this != &str)
    {
        String tmp(str);
        swap(tmp);
    }
    return *this;
}

// String& String::operator= (String str)
// {
//     swap(str);
//     return *this; //注意_str需要置为nullptr
// }

void String::swap(String& str)
{
    std::swap(_str, str._str);
    std::swap(_size, str._size);
    std::swap(_capacity, str._capacity);
}

String String::substr(size_t pos, size_t len) const
{
    assert(pos < _size);

    if(len > _size - pos) len = _size - pos;
    String res;
    res.reserve(len);
    for(int i = 0; i < len; i++)
        res.push_back(_str[pos + i]);
    return res;
}


bool String::operator< (const String& str) const
{
    int i = 0;
    for(; i < _size && i < str._size; i++)
        if(_str[i] != str._str[i])
            return _str[i] < str._str[i];
    if(i == _size) return true;
    return false;
}
bool String::operator> (const String& str) const
{
    int i = 0;
    for(; i < _size && i < str._size; i++)
        if(_str[i] != str._str[i])
            return _str[i] > str._str[i];
    if(i == str._size) return true;
    return false;
}
bool String::operator== (const String& str) const
{
    if(_size != str._size) return false;
    for(int i = 0; i < _size; i++)
        if(_str[i] != str._str[i])
            return false;
    return true;
}
bool String::operator!= (const String& str) const
{
    return !(*this == str);
}
bool String::operator<= (const String& str) const
{
    return *this < str || *this == str;
}
bool String::operator>= (const String& str) const
{
    return *this > str || *this == str;
}

ostream& operator<< (ostream& out, const String& str)
{
    cout << str.c_str();
    return out;
}

istream& operator>> (istream& in, String& str)
{
    str.clear();
    // // char c = getchar(); // 不要用in >> c; 会自动过滤空格/换行
    // char c = in.get();
    // while(c != ' ' && c != '\n' && c != '\t')
    // {
    //     str.push_back(c);
    //     // c = getchar();
    //     c = in.get();
    // }

    // 优化
    char buff[1010] = "";
    int i = 0;
    while(buff[i] = in.get(), buff[i] != ' ' && buff[i] != '\n' && buff[i] != '\t')
    {
        i++;
        if(i == 1000)
        {
            str += buff;
            i = 0;
        }
    }
    buff[i] = '\0';
    str += buff;
    return in;
}